//	Created by Youhua Xu
//	Configure DCDS position parameters

#include "SchmidtCAM.h"

void dcds_cfg_clk( uint* reg );
void dcds_cfg_rst( uint* reg );

#define REG_NUM 17	// 16 mask[16] + 1 add_sub[16]
//	16来自于需要对PL端一个长度为256bits的寄存器进行配置,而SPI每次发送16bits.

int main( int argc, char *argv[] ){

	if( argc < 2 ){
		printf("usage: %s dcds_cfg.ini\n", argv[0]);
		return 0;
	}

	char ini_fname[128];
	sprintf(ini_fname, "%s", argv[1]);

	dictionary *ini;
	ini = iniparser_load(ini_fname);
	if( ini == NULL ){
		fprintf(stderr, "cannot parse file: %s\n", ini_fname);
		return 0;
	}

	uint reg_vals[REG_NUM] = {0};

//	读取配置参数
	int add_sub_pos = iniparser_getint(ini, "DCDS_CFG:dcds_add_sub_pos", 	1);
	reg_vals[REG_NUM-1] = add_sub_pos;

	int mask_pos1 = iniparser_getint(ini, "DCDS_CFG:mask_pos1", 	0);
	int mask_pos2 = iniparser_getint(ini, "DCDS_CFG:mask_pos2", 	1);
	int mask_pos3 = iniparser_getint(ini, "DCDS_CFG:mask_pos3", 	2);
	int mask_pos4 = iniparser_getint(ini, "DCDS_CFG:mask_pos4", 	3);

	int i, j;
	int bit_count = 0;	// start from 0, ends at 256
	
	//  16*16
	for( i=0; i<16; i++ ){
		reg_vals[i] = 0;
		for( j=0; j<16; j++ ){

			int bit = ((bit_count >= mask_pos1) && (bit_count <= mask_pos2)) 
			        || ((bit_count >= mask_pos3) && (bit_count <= mask_pos4));
			        
			if( bit == 1 ){
				setbit(reg_vals[i], j);
			}

			// clrbit(reg_vals[i], j); // for debug only
			
			bit_count++;
		}
	}

	if( bit_count != 256 ){
		printf("** %s, L:%d **: bit_count dose not equal to 256!\n", __FILE__, __LINE__);
		exit(0);
	}


	int fd = open("/dev/mem", O_RDWR | O_SYNC);
	uint *ptr1 = mmap(NULL, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADDR_GPIO_OUT);
	uint *gpio_reg 		= ptr1;		// 0x41200000
	uint *gpio2_reg		= ptr1+2;	// 0x41200008

	// dcds_cfg_rst(gpio_reg);	// 触发reset信号
	// dcds_cfg_clk(gpio_reg);	// IDLE state

	// for( i=0; i<REG_NUM; i++ ){
	// 	*gpio2_reg = reg_vals[i];   // 16 addr bits + 16 data bits
	// 	dcds_cfg_clk(gpio_reg);
	// }

	// usleep(1000);

	SPI_PS_SEND_DATA( 	gpio_reg,
						gpio2_reg,
						reg_vals,
						REG_NUM,
						SPI_PS_DCDS );

	munmap(ptr1,10);
	close(fd);

	iniparser_freedict(ini);

	return 0;
}

void dcds_cfg_clk( uint* reg ){
	clrbit(*reg, BIT_SPI_PS_SCLK);
	setbit(*reg, BIT_SPI_PS_SCLK);
}

void dcds_cfg_rst( uint* reg ){
	clrbit(*reg, BIT_SPI_PS_RST);
	setbit(*reg, BIT_SPI_PS_RST);
	clrbit(*reg, BIT_SPI_PS_RST);
}
